package com.example.democlient.network.handler;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

import android.annotation.SuppressLint;

import com.example.democlient.network.ServerConnection;
import com.example.democlient.network.ServerConnection.State;
import com.example.democlient.network.packet.ClientPacket;

@SuppressLint({ "UseSparseArrays", "UseSparseArrays" })
public class PacketHandler
{
	/**
	 * logger for this class
	 */
	private Map<State, Map<Integer, ClientPacket>>	packetPrototypes	= new HashMap<State, Map<Integer, ClientPacket>>();

	/**
	 * Reads one packet from given ByteBuffer
	 * 
	 * @param data
	 * @param client
	 * @return GsClientPacket object from binary data
	 */
	public ClientPacket handle(ByteBuffer data, ServerConnection client)
	{
		State state = client.getState();
		int id = data.get() & 0xff;

		return getPacket(state, id, data, client);
	}

	/**
	 * 
	 * @param packetPrototype
	 * @param states
	 */
	public void addPacketPrototype(ClientPacket packetPrototype, State... states)
	{
		for(State state : states)
		{
			Map<Integer, ClientPacket> pm = packetPrototypes.get(state);
			if(pm == null)
			{
				pm = new HashMap<Integer, ClientPacket>();
				packetPrototypes.put(state, pm);
			}
			pm.put(packetPrototype.getOpcode(), packetPrototype);
		}
	}

	/**
	 * 
	 * @param state
	 * @param id
	 * @param buf
	 * @param con
	 * @return
	 */
	private ClientPacket getPacket(State state, int id, ByteBuffer buf, ServerConnection con)
	{
		ClientPacket prototype = null;

		Map<Integer, ClientPacket> pm = packetPrototypes.get(state);
		if(pm != null)
		{
			prototype = pm.get(id);
		}

		if(prototype == null)
		{
			unknownPacket(state, id);
			return null;
		}

		ClientPacket res = prototype.clonePacket();
		res.setBuffer(buf);
		res.setConnection(con);

		return res;
	}

	/**
	 * Logs unknown packet.
	 * 
	 * @param state
	 * @param id
	 */
	private void unknownPacket(State state, int id)
	{
		System.out.println(String.format("Unknown packet recived from Chat Server: 0x%02X state=%s", id, state.toString()));
	}
}
